'''
''' IBAN Functions - IBANDefinitions.vb
'''
''' This program is free software; you can redistribute it and/or modify
''' it under the terms of the GNU General Public License as published by
''' the Free Software Foundation; either version 2 of the License, or
''' (at your option) any later version.
'''
''' This program is distributed in the hope that it will be useful,
''' but WITHOUT ANY WARRANTY; without even the implied warranty of
''' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
''' GNU General Public License for more details.
'''
''' You should have received a copy of the GNU General Public License
''' along with this program; if not, write to the Free Software
''' Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
'''

Imports System.Xml

''' -----------------------------------------------------------------------------
''' Project	 : IBANFuncsCore
''' Class	 : Core.IBANDefinitions
''' 
''' -----------------------------------------------------------------------------
''' <summary>
''' This class provides shared (static) methods to read and manipulate
''' the IBAN country definitions.
''' </summary>
''' <remarks>
''' </remarks>
''' <history>
''' 	[Nick]	2/8/2007	Created
''' </history>
''' -----------------------------------------------------------------------------
Public Class IBANDefinitions

#Region "Class variables"

    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' Internal shared (static) representation of all country definitions.
    ''' </summary>
    ''' <remarks>
    ''' </remarks>
    ''' <history>
    ''' 	[Nick]	2/8/2007	Created
    ''' </history>
    ''' -----------------------------------------------------------------------------
    Private Shared _Countries As New Hashtable

    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' Internal representation of the minimum IBAN length.
    ''' </summary>
    ''' <remarks>
    ''' </remarks>
    ''' <history>
    ''' 	[Nick]	2/8/2007	Created
    ''' </history>
    ''' -----------------------------------------------------------------------------
    Private Shared _MinLength As Integer = 9999

    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' Internal representation of the maximum IBAN length.
    ''' </summary>
    ''' <remarks>
    ''' </remarks>
    ''' <history>
    ''' 	[Nick]	2/8/2007	Created
    ''' </history>
    ''' -----------------------------------------------------------------------------
    Private Shared _MaxLength As Integer = 0

#End Region

#Region "Properties"

    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' Property to get the maximum IBAN length.
    ''' </summary>
    ''' <value>Integer with maximum IBAN length.</value>
    ''' <remarks>
    ''' </remarks>
    ''' <history>
    ''' 	[Nick]	2/8/2007	Created
    ''' </history>
    ''' -----------------------------------------------------------------------------
    Public Shared ReadOnly Property MaxIBANLength() As Integer
        Get
            Return _MaxLength
        End Get
    End Property

    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' Property to get the minimum IBAN length.
    ''' </summary>
    ''' <value>Integer with minimum IBAN length.</value>
    ''' <remarks>
    ''' </remarks>
    ''' <history>
    ''' 	[Nick]	2/8/2007	Created
    ''' </history>
    ''' -----------------------------------------------------------------------------
    Public Shared ReadOnly Property MinIBANLength() As Integer
        Get
            Return _MinLength
        End Get
    End Property

#End Region

#Region "Initializer"

    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' This method reads the IBAN definitions XML file.
    ''' </summary>
    ''' <param name="XMLParameters">Path to IBANDefinitions.xml.</param>
    ''' <remarks>
    ''' This method <b>must</b> be called before using any of the functions
    ''' of this library.
    ''' </remarks>
    ''' <history>
    ''' 	[Nick]	2/8/2007	Created
    ''' </history>
    ''' -----------------------------------------------------------------------------
    Public Shared Sub ReadDefinitions(ByVal XMLParameters As String)

        Try
            _Countries = New Hashtable

            Dim reader As XmlTextReader = New XmlTextReader(XMLParameters)

            reader.WhitespaceHandling = WhitespaceHandling.None
            reader.MoveToContent()
            reader.Read()

            Dim doc As XmlDocument = New Xml.XmlDocument
            doc.Load(reader)

            'Locate all <Country>
            Dim x As Xml.XmlElement = doc.DocumentElement("Country")
            Dim cntr As Integer = 0

            While Not (x Is Nothing)

                Dim def As New IBANCountryDef(x)

                'Sanitize lengths
                If def.BankCodeLength + _
                   def.BranchCodeLength + _
                   def.AccountNumberLength + 4 <> _
                   def.IBANLength Then Throw New Exception("Country " + def.CountryCode + " has invalid lengths")

                'Track min/max lengths
                If def.IBANLength < _MinLength Then
                    _MinLength = def.IBANLength
                End If

                If def.IBANLength > _MaxLength Then
                    _MaxLength = def.IBANLength
                End If

                _Countries.Add(def.CountryCode, def)

                'Next one
                x = x.NextSibling

            End While

        Catch ex As Exception

            Throw New XIBANDefinitionsReadException(ex.ToString)

        End Try

    End Sub

#End Region

#Region "Methods"

    'Returns a country class if it matches the country code
    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' Returns the <see cref="IBANCountryDef"/> that matches a country code.
    ''' </summary>
    ''' <param name="countryCode">String representation of the country code to search for.</param>
    ''' <returns><see cref="IBANCountryDef"/> instance or Nothing (null).</returns>
    ''' <remarks>
    ''' </remarks>
    ''' <history>
    ''' 	[Nick]	2/8/2007	Created
    ''' </history>
    ''' -----------------------------------------------------------------------------
    Public Shared Function FindCountryByCode(ByVal countryCode As String) As IBANCountryDef

        Return _Countries(countryCode)

    End Function

    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' Returns the number of countries for which there are definitions loaded.
    ''' </summary>
    ''' <returns>Number of loaded country definitions.</returns>
    ''' <remarks>
    ''' </remarks>
    ''' <history>
    ''' 	[Nick]	2/8/2007	Created
    ''' </history>
    ''' -----------------------------------------------------------------------------
    Public Shared Function GetNumberCountries() As Integer

        Return _Countries.Count

    End Function

    'Returns a specific country by index (0-based)
    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' Returns a country definitions by index (0-based).
    ''' </summary>
    ''' <param name="index">Index value.</param>
    ''' <returns><see cref="IBANCountryDef"/> instance or Nothing (null).</returns>
    ''' <remarks>
    ''' </remarks>
    ''' <history>
    ''' 	[Nick]	2/8/2007	Created
    ''' </history>
    ''' -----------------------------------------------------------------------------
    Public Shared Function GetCountry(ByVal index As Integer) As IBANCountryDef

        Dim en As IDictionaryEnumerator = _Countries.GetEnumerator()
        en.Reset()
        For i As Integer = 0 To index
            en.MoveNext()
        Next
        Dim def As IBANCountryDef = en.Value
        en = Nothing
        Return def

    End Function

#End Region

End Class